package in.rob.client;
import in.lib.Constants;
import in.lib.Debug;
import in.lib.annotation.InjectView;
import in.lib.handler.base.LoginResponseHandler;
import in.lib.handler.base.UserResponseHandler;
import in.lib.handler.base.UserStreamResponseHandler;
import in.lib.manager.APIManager;
import in.lib.manager.CacheManager;
import in.lib.manager.ImageAPIManager;
import in.lib.manager.UserManager;
import in.lib.receiver.NotificationReceiver;
import in.lib.utils.ADNPassportUtility;
import in.lib.utils.Views;
import in.model.SimpleUser;
import in.model.User;
import in.model.base.NetObject;
import in.obj.Auth;
import in.rob.client.MainApplication.ApplicationType;
import in.rob.client.base.RobinActivity;
import in.rob.client.dialog.base.DialogBuilder;
import in.rob.client.dialog.base.ProgressBuilder;
import in.rob.client.page.UserFriendsPage;
import java.util.ArrayList;
import java.util.List;
import net.callumtaylor.asynchttp.AsyncHttpClient;
import net.callumtaylor.asynchttp.obj.entity.JsonEntity;
import net.callumtaylor.asynchttp.response.JsonResponseHandler;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.Html;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
public class AuthenticateActivity extends RobinActivity implements OnEditorActionListener
{
@InjectView(R.id.username) public EditText mUsername;
@InjectView(R.id.password) public EditText mPassword;
@InjectView(R.id.beta_build) public TextView mBetaBuild;
@InjectView(R.id.login_button) public Button mLoginButton;
@InjectView(R.id.cd_key) public EditText mCdKey;
@InjectView(R.id.cd_key_container) public View mCdKeyContainer;
private ProgressDialog progress;
private final BroadcastReceiver installReceiver = new BroadcastReceiver()
{
@Override public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
String dataString = intent.getDataString();
if (Intent.ACTION_PACKAGE_ADDED.equals(action) && dataString.equals(String.format("package:%s", ADNPassportUtility.APP_PACKAGE)))
{
adnButtonClick(null);
}
}
};
@Override public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login_view);
Views.inject(this);
if (getIntent() != null && ((MainApplication)getApplication()).getApplicationType() == ApplicationType.CD_KEY)
{
if (getIntent().getData() != null)
{
Uri data = getIntent().getData();
mCdKey.setText(data.getQueryParameter("key"));
}
}
if (getIntent().getExtras() == null || !getIntent().getExtras().getBoolean(Constants.EXTRA_NEW_USER, false))
{
if (!TextUtils.isEmpty(UserManager.getAccessToken()))
{
startMainActivity();
finish();
return;
}
}
setTitle(R.string.login_title);
if (progress == null)
{
progress = ProgressBuilder.create(getContext());
progress.setMessage(getString(R.string.logging_in));
progress.setCanceledOnTouchOutside(false);
if (savedInstanceState != null && savedInstanceState.containsKey(Constants.EXTRA_SHOWING_PROGRESS))
{
if (savedInstanceState.getBoolean(Constants.EXTRA_SHOWING_PROGRESS))
{
progress.show();
}
}
}
if (((MainApplication)getApplication()).getApplicationType() == ApplicationType.CD_KEY)
{
mCdKeyContainer.setVisibility(View.VISIBLE);
mPassword.setImeOptions(EditorInfo.IME_ACTION_NEXT);
try
{
String key = CacheManager.getInstance().readFileAsObject(Environment.getExternalStorageDirectory().getAbsolutePath() + "/robin.cdkey", String.class);
if (key != null)
{
mCdKey.setText(key);
}
else
{
SharedPreferences prefs = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
mCdKey.setText(prefs.getString(Constants.PREFS_CD_KEY, ""));
}
}
catch (Exception e){}
}
if (((MainApplication)getApplication()).getApplicationType() == ApplicationType.BETA)
{
try
{
PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
findViewById(R.id.beta_container).setVisibility(View.VISIBLE);
mBetaBuild.setText("Beta build number: " + info.versionCode);
}
catch (Exception e) {}
}
mPassword.setOnEditorActionListener(this);
}
@Override protected void onSaveInstanceState(Bundle outState)
{
outState.putBoolean(Constants.EXTRA_SHOWING_PROGRESS, progress.isShowing());
progress.dismiss();
super.onSaveInstanceState(outState);
}
public void adnButtonClick(View v)
{
if (ADNPassportUtility.isPassportAuthorizationAvailable(this))
{
Intent i = ADNPassportUtility.getAuthorizationIntent(APIManager.CLIENT_TOKEN, APIManager.API_SCOPES_CSV);
startActivityForResult(i, Constants.REQUEST_CODE_AUTHORIZE);
}
else
{
ADNPassportUtility.launchPassportInstallation(this);
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
registerReceiver(installReceiver, filter);
}
}
@Override protected void onDestroy()
{
super.onDestroy();
try
{
unregisterReceiver(installReceiver);
}
catch (Exception e){}
}
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Constants.REQUEST_CODE_AUTHORIZE)
{
if (resultCode == 1)
{
String username = data.getStringExtra("username");
String accessToken = data.getStringExtra("accessToken");
String userId = data.getStringExtra("userId");
progress.show();
if (((MainApplication)getApplication()).getApplicationType() == ApplicationType.BETA)
{
checkBetaKeyLogin(accessToken, userId, username);
}
else
{
downloadUser(accessToken, userId);
}
}
}
}
/**
* Called when the login button is hit
* @param v The login button (dont use this as it can be called from keyboard IME)
*/
public void loginButtonClick(View v)
{
String usernameStr = mUsername.getText().toString();
String passwordStr = mPassword.getText().toString();
mUsername.setHintTextColor(getResources().getColor(R.color.light_login_hint));
mPassword.setHintTextColor(getResources().getColor(R.color.light_login_hint));
if (TextUtils.isEmpty(usernameStr))
{
mUsername.setHintTextColor(getResources().getColor(R.color.light_login_hint_error));
return;
}
else
{
mUsername.setHintTextColor(getResources().getColor(R.color.light_login_hint));
}
if (TextUtils.isEmpty(passwordStr))
{
mPassword.setHintTextColor(getResources().getColor(R.color.light_login_hint_error));
return;
}
else
{
mPassword.setHintTextColor(getResources().getColor(R.color.light_login_hint));
}
if (((MainApplication)getApplication()).getApplicationType() == ApplicationType.BETA)
{
progress.show();
checkBetaKeyLogin(usernameStr, passwordStr);
return;
}
else if (((MainApplication)getApplication()).getApplicationType() == ApplicationType.CD_KEY)
{
mCdKey.setError(null);
String key = mCdKey.getText().toString();
// perform some initial checks
boolean verified = false;
boolean okToCheck = true;
okToCheck &= key.length() == 23;
okToCheck &= key.replaceAll("[0-9a-zA-Z]", "").length() == 3;
okToCheck &= key.replaceAll("[0-9A-Za-z\\-]", "").length() == 0;
if (okToCheck)
{
verified = in.rob.keygen.Main.v(key);
}
if (!okToCheck || !verified)
{
mCdKey.setError("Invalid key");
return;
}
}
progress.show();
loginUser(usernameStr, passwordStr);
}
public void checkBetaKeyLogin(final String username, final String password)
{
try
{
final AsyncHttpClient checker = new AsyncHttpClient(Constants.API_BETA_URL);
JsonObject data = new JsonObject();
data.addProperty("token", "");
data.addProperty("username", username);
data.addProperty("device_id", getDeviceId());
data.addProperty("version", getString(R.string.app_version));
progress.setOnCancelListener(new OnCancelListener()
{
@Override public void onCancel(DialogInterface dialog)
{
checker.cancel();
}
});
JsonEntity postData = new JsonEntity(data);
checker.post(Constants.API_BETA_CHECK, postData, new JsonResponseHandler()
{
@Override public void onSuccess(){}
@Override public void onFinish(boolean failed)
{
if (failed)
{
Debug.out(getConnectionInfo());
progress.dismiss();
if (getConnectionInfo().responseCode == 401)
{
DialogBuilder.create(getContext())
.setTitle(R.string.error)
.setMessage(R.string.beta_error)
.setPositiveButton(R.string.close, null)
.show();
}
else
{
DialogBuilder.create(getContext())
.setTitle(R.string.error)
.setMessage(R.string.login_error)
.setPositiveButton(R.string.close, null)
.show();
}
}
else
{
SharedPreferences.Editor editor = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE).edit();
editor.putBoolean(Constants.PREFS_HAS_BETA, true).apply();
loginUser(username, password);
}
}
});
}
catch (Exception e)
{
Debug.out(e);
}
}
public void checkBetaKeyLogin(final String accessToken, final String userId, String username)
{
try
{
final AsyncHttpClient checker = new AsyncHttpClient(Constants.API_BETA_URL);
JsonObject data = new JsonObject();
data.addProperty("token", "");
data.addProperty("username", username);
data.addProperty("device_id", getDeviceId());
data.addProperty("version", getString(R.string.app_version));
progress.setOnCancelListener(new OnCancelListener()
{
@Override public void onCancel(DialogInterface dialog)
{
checker.cancel();
}
});
JsonEntity postData = new JsonEntity(data);
checker.post(Constants.API_BETA_CHECK, postData, new JsonResponseHandler()
{
@Override public void onSuccess(){}
@Override public void onFinish(boolean failed)
{
if (failed)
{
Debug.out(getConnectionInfo());
progress.dismiss();
if (getConnectionInfo().responseCode == 401)
{
DialogBuilder.create(getContext())
.setTitle(R.string.error)
.setMessage(R.string.beta_error)
.setPositiveButton(R.string.close, null)
.show();
}
else
{
DialogBuilder.create(getContext())
.setTitle(R.string.error)
.setMessage(R.string.login_error)
.setPositiveButton(R.string.close, null)
.show();
}
}
else
{
SharedPreferences.Editor editor = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE).edit();
editor.putBoolean(Constants.PREFS_HAS_BETA, true).apply();
downloadUser(accessToken, userId);
}
}
});
}
catch (Exception e)
{
Debug.out(e);
}
}
public void infoButtonClick(View v)
{
String information = getString(R.string.login_info_description_1) +
"<br /><br />" +
getString(R.string.login_info_description_2) +
"<br /><br />" +
" <b>" + getString(R.string.stream) + "</b><br />" + getString(R.string.stream_desc) + "<br /><br />" +
" <b>" + getString(R.string.email) + "</b><br />" + getString(R.string.email_desc) + "<br /><br />" +
" <b>" + getString(R.string.write_post) + "</b><br />" + getString(R.string.write_post_desc) + "<br /><br />" +
" <b>" + getString(R.string.follow) + "</b><br />" + getString(R.string.follow_desc) + "<br /><br />" +
" <b>" + getString(R.string.messages) + "</b><br />" + getString(R.string.messages_desc) + "<br /><br />" +
" <b>" + getString(R.string.update_profile) + "</b><br />" + getString(R.string.update_profile_desc) + "<br /><br />" +
" <b>" + getString(R.string.files) + "</b><br />" + getString(R.string.files_desc) + "<br /><br />" +
getString(R.string.login_info_description_3);
DialogBuilder.create(getContext())
.setTitle(R.string.information)
.setMessage(Html.fromHtml(information))
.setPositiveButton(R.string.close, null)
.show();
}
/**
* Initiates the login call and downloads the user's profile data
* @param username The username of the user logging in
* @param password The password of the user logging in
*/
public void loginUser(String username, String password)
{
final AsyncHttpClient request = APIManager.getInstance().login(username, password, getContext(), new LoginResponseHandler()
{
@Override public void onCallback()
{
if (((MainApplication)getApplication()).getApplicationType() == ApplicationType.CD_KEY)
{
try
{
CacheManager.getInstance().writeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/robin.cdkey", mCdKey.getText().toString());
}
catch (Exception e){}
SharedPreferences prefs = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
prefs.edit().putString(Constants.PREFS_CD_KEY, mCdKey.getText().toString()).apply();
APIManager.getInstance().logAccess(getApplicationContext(), "" + getUserId(), mCdKey.getText().toString(), getDeviceId());
}
downloadUser(getAccessToken(), "" + getUserId());
}
@Override public void onFinish(boolean failed)
{
if (failed)
{
progress.dismiss();
String errorMessage = getString(R.string.vague_error);
try
{
JsonElement data = getContent();
JsonObject returnedData = data.getAsJsonObject();
errorMessage = returnedData.get("error").getAsString();
}
catch (Exception e){}
mUsername.setTextColor(getResources().getColor(R.color.light_login_text_error));
mPassword.setTextColor(getResources().getColor(R.color.light_login_text_error));
DialogBuilder.create(getContext())
.setTitle(getString(R.string.error))
.setMessage(errorMessage)
.setPositiveButton(getString(R.string.close), null)
.show();
}
}
});
progress.setOnCancelListener(new OnCancelListener()
{
@Override public void onCancel(DialogInterface dialog)
{
request.cancel();
}
});
}
/**
* Downloads the user profile and stores it in a cahced file
* @param accessToken The access token of the user
* @param userId The user id of the user
*/
public void downloadUser(final String accessToken, final String userId)
{
Auth a = new Auth();
a.setAccessToken(accessToken);
UserManager.setAuth(a);
UserManager.setAccessToken(accessToken);
UserManager.setUserId(userId);
APIManager.getInstance().getUserDetails(userId, new UserResponseHandler(getApplicationContext())
{
@Override public void onSuccess()
{
super.onSuccess();
if (getFilesDir() != null)
{
CacheManager.getInstance().writeFile(getFilesDir().getAbsolutePath() + "user_" + getUser().getId(), getUser());
}
getUser().save();
UserManager.addUser(getUser(), UserManager.getAuth(), getApplicationContext());
UserManager.setUser(getUser(), getApplicationContext());
new NotificationReceiver().registerUserForPush(getApplicationContext());
}
@Override public void onFinish()
{
Debug.out(getConnectionInfo());
if (getUser() != null)
{
// Download the user's cover image
ImageLoader coverImageLoader = ImageLoader.getInstance();
coverImageLoader.loadImage(getUser().getCoverUrl(), MainApplication.getMediaImageOptions(), new ImageLoadingListener()
{
@Override public void onLoadingStarted(String arg0, View arg1){}
@Override public void onLoadingCancelled(String arg0, View arg1)
{
progress.dismiss();
startMainActivity();
}
@Override public void onLoadingComplete(String arg0, View arg1, Bitmap arg2)
{
progress.dismiss();
startMainActivity();
}
@Override public void onLoadingFailed(String arg0, View arg1, FailReason arg2)
{
progress.dismiss();
startMainActivity();
}
});
getImageDelegateToken();
getFollowingList();
}
else
{
progress.dismiss();
String errorMessage = getString(R.string.vague_error);
DialogBuilder.create(getContext())
.setTitle(getString(R.string.error))
.setMessage(errorMessage)
.setPositiveButton(getString(R.string.close), null)
.show();
}
}
@Override public void onCallback(){}
});
}
/**
* Gets the image delegation token for the initial image service
*/
public void getImageDelegateToken()
{
ImageAPIManager.getInstance().registerForToken(getContext(), UserManager.getUser());
}
/**
* Used to build an initial list of users for the auto complete
*/
public void getFollowingList()
{
APIManager.getInstance().getUserFollowing(UserManager.getUserId(), "", new UserStreamResponseHandler(getApplicationContext(), false)
{
@Override public void onCallback()
{
List<SimpleUser> users = CacheManager.getInstance().readFileAsObject(Constants.CACHE_USERNAMES, new ArrayList<SimpleUser>());
for (NetObject u : getObjects())
{
SimpleUser user = SimpleUser.parseFromUser((User)u);
if (!SimpleUser.containsUser(users, user))
{
users.add(user);
}
}
CacheManager.getInstance().asyncWriteFile(String.format(Constants.CACHE_USER_LIST_NAME, UserFriendsPage.Mode.FOLLOWING.getModeText(), UserManager.getUserId()), getObjects());
CacheManager.getInstance().asyncWriteFile(Constants.CACHE_USERNAMES, users);
}
});
}
public void startMainActivity()
{
Intent main = new Intent(this, MainActivity.class);
main.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
main.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
main.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
main.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(main);
finish();
}
@Override public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.empty, menu);
return super.onCreateOptionsMenu(menu);
}
@Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
if (actionId == EditorInfo.IME_ACTION_GO)
{
mLoginButton.performClick();
return true;
}
return false;
}
}